#pragma once

#include "Vector2D.h"

namespace AGE
{ 
    /**
     * @brief Provides notications for mouse input
     * @author Andrew Caci
     * @date December 16, 2009
     *
     * Mouse notifications such as ouse move, button click
     *
     */
    class IMouseNotification
    {
		friend class GameEngine;

    public:

        virtual ~IMouseNotification() {}

        /**
         * @brief When the mouse is moved
         *
         * @param iPosition The new x,y coordinates of the mouse
         * @param iRelativePosition The x,y coordinates relative to the previous mouse position
         */
        virtual void OnMouseMotion(const Vector2D<Uint32>& iPosition, const Vector2D<Sint32>& iRelativePosition) = 0;

        /**
         * @brief When a mouse button is pushed down
         *
         * @param iButton The SDL_BUTTON pushed (SDL_BUTTON_LEFT, SDL_BUTTON_MIDDLE, SDL_BUTTON_RIGHT)
         * @param iPosition The new x,y coordinates of the mouse
         */
        virtual void OnMouseButtonDown(Uint8 iButton, const Vector2D<Uint32>& iPosition)                         = 0;

        /**
         * @brief When a mouse button is released
         *
         * @param iButton The SDL_BUTTON pushed (SDL_BUTTON_LEFT, SDL_BUTTON_MIDDLE, SDL_BUTTON_RIGHT)
         * @param iPosition The new x,y coordinates of the mouse
         */
        virtual void OnMouseButtonUp(Uint8 iButton, const Vector2D<Uint32>& iPosition)                           = 0;
    
        /**
         * @brief Tests whether or not a mouse button is down
         * 
         * @param iButton The SDL_BUTTON to test for
         * 
         * @return iButton Whether or not the SDL_BUTTON is down
         */
        inline bool IsMouseButtonDown(Uint8 iButton)
        {
            return (m_MouseKeys & iButton) != 0;
        }

        /**
         * @brief Tests whether or not a mouse button is up
         * 
         * @param iButton The SDL_BUTTON to test for
         * @return Whether or no the SDL_BUTTON is down
         */
        inline bool IsMouseButtonUp(Uint8 iButton)
        {
            return !IsMouseButtonDown(iButton);
        }

        /**
         * @brief Gets the current x,y coordinates of the mouse
         * 
         * @return The x,y coordinates of the mouse
         */
        inline const Vector2D<Uint32>& getMousePosition() const
        {
            return m_MousePosition;
        }

        static const Uint8 cLeftMouseButton   = 1;
        static const Uint8 cMiddleMouseButton = 2;
        static const Uint8 cRightMouseButton  = 3;

    private:

		inline void SetMouseState( Uint8 iMouseKeys )
		{
			m_MouseKeys = iMouseKeys;
		}

        Vector2D<Uint32> m_MousePosition;
        Vector2D<Sint32> m_MouseRelativePosition;
        Uint8            m_MouseKeys;
    };
}